package org.example.fancystudy.cas;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicStampedReference;

/**
 * @author chaigq
 * @version 1.0
 * @date 2023/2/17 16:02
 */
public class ABADemo {
//    static AtomicInteger atomicInteger = new AtomicInteger(100);
//
//    public static void main(String[] args) {
//        new Thread(() -> {
//            atomicInteger.compareAndSet(100, 101);
//            try {
//                TimeUnit.MILLISECONDS.sleep(10);
//                System.out.println("被我修改过了" + atomicInteger.get());
//                atomicInteger.compareAndSet(101, 100);
//                System.out.println("我又改回去了" + atomicInteger.get());
//            }catch (InterruptedException e){
//                e.printStackTrace();
//            }
//        },"A").start();
//
//        new Thread(() -> {
//            try {
//                TimeUnit.MILLISECONDS.sleep(200);
//            }catch (InterruptedException e){
//                e.printStackTrace();
//            }
//            atomicInteger.compareAndSet(100, 2023);
//            System.out.println("我修改了" + atomicInteger.get());
//        },"B").start();
//    }

    static AtomicStampedReference<Integer> atomicStampedReference = new AtomicStampedReference<>(100, 1);

    public static void main(String[] args) {
        new Thread(() -> {
            int stamp = atomicStampedReference.getStamp();
            System.out.println(Thread.currentThread().getName()+"\t"+"首次版本号："+stamp + "\t" + "初始值：" + atomicStampedReference.getReference());
            try {
                TimeUnit.MILLISECONDS.sleep(100);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
            atomicStampedReference.compareAndSet
                    (100, 101, atomicStampedReference.getStamp(), atomicStampedReference.getStamp()+1);
            System.out.println(Thread.currentThread().getName()+"\t"+"2次版本号："+atomicStampedReference.getStamp() + "\t" + "修改值：" + atomicStampedReference.getReference());

            atomicStampedReference.compareAndSet
                    (101, 100, atomicStampedReference.getStamp(), atomicStampedReference.getStamp()+1);
            System.out.println(Thread.currentThread().getName()+"\t"+"3次版本号："+atomicStampedReference.getStamp() + "\t" + "修改值：" + atomicStampedReference.getReference());
        }, "C").start();

        new Thread(() -> {
            int stamp = atomicStampedReference.getStamp();
            int reference = atomicStampedReference.getReference();
            System.out.println(Thread.currentThread().getName()+"\t"+"首次版本号："+stamp + "\t" + "初始值：" + reference);

            //暂停1秒钟线程,等待上面的线程，发生了ABA问题
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            boolean b = atomicStampedReference.compareAndSet(100, 2022, stamp, stamp + 1);
            System.out.println(b+"\t"+ "当前值：" + atomicStampedReference.getReference()+"\t"+ "当前版本号：" +atomicStampedReference.getStamp() );

        },"D").start();
    }
}
